package com.bestv.lucene;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.document.*;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

import java.io.File;
import java.io.FileFilter;
import java.io.FileReader;
import java.io.IOException;

/**
 * 文件索引器
 * User: Henry
 * Date: 14-5-6
 */
public class FileIndexer {

    private IndexWriter indexWriter;

    /**
     * 构造索引器
     * @param indexDir 生成索引所在位置的完整路径
     * @throws IOException
     */
    public FileIndexer(String indexDir) throws IOException {
        Directory dir = FSDirectory.open(new File(indexDir));
        Analyzer analyzer = new CJKAnalyzer();
        IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_4_10_4, analyzer);
        iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND);
        indexWriter = new IndexWriter(dir, iwc);
    }

    public void close() throws IOException {
        indexWriter.close();
    }

    public int index(String dataDir, FileFilter fileFilter) throws IOException {
        File[] files = new File(dataDir).listFiles();
        assert files != null;
        for (File f : files) {
            if (f.isDirectory()
                    | f.isHidden()
                    | !f.exists()
                    | !f.canRead()
                    | (fileFilter != null && !fileFilter.accept(f))) {
                continue;
            }
            indexFile(f);
        }
        return indexWriter.numDocs();
    }

    private void indexFile(File f) throws IOException {
        Document doc = getDocument(f);
        indexWriter.updateDocument(new Term("path", f.getPath()), doc);
    }

    private Document getDocument(File f) throws IOException {
        Document doc = new Document();
        doc.add(new StringField("path", f.getPath(), Field.Store.YES));
        doc.add(new LongField("modified", f.lastModified(), Field.Store.NO));
        doc.add(new TextField("content", new FileReader(f)));
        return doc;
    }
}
